import { Injectable, Logger } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Task } from "./task.entities";
import { Repository } from "typeorm";
import { AccountService } from "../account/account.service";
import { RedisCacheService } from "../../redis/rediscache.service";
import { QuantityExceededException } from "../../exception/count.limit.exception";

@Injectable()
export class TasksService {
  private readonly logger = new Logger();
  constructor(
    private readonly cacheService: RedisCacheService,
    @InjectRepository(Task)
    private taskRepository: Repository<Task>
  ) {}

  async createTask(task: Task, repeat: boolean = false): Promise<Task> {
    let redisOk = true;
    try {
      //检查今日任务数量
      await this.checkTodayTaskCount(task);
    } catch (err) {
      redisOk = false;
      return Promise.reject(err);
    }

    try {
      //如果不要求重复生成，则先查询是否已经生成过
      if (!repeat) {
        //先通过prompt查询，有则返回，无则创建
        const taskByPrompt = await this.getTaskByPrompt(task.prompt);
        if (taskByPrompt != null) {
          taskByPrompt.emp_id = task.emp_id;
          taskByPrompt.emp_name = task.emp_name;
          taskByPrompt.email = task.email;
          taskByPrompt.modified_time = task.modified_time;
          taskByPrompt.id = null;
          taskByPrompt.created_time = task.created_time;

          task = taskByPrompt;

          return await this.taskRepository.save(task);
        }
      }

      const saveTask = await this.taskRepository.save(task);
      this.sendImageTask(task);
      return saveTask;
    } catch (err) {
      // redis任务使用次数增加了，但是任务生成失败了，需要将次数减一
      if (redisOk) {
        this.taskCountDecr(task);
      }
      return Promise.reject(err);
    }
  }

  /** 检查当天累计生成的次数，并且加1 */
  private async checkTodayTaskCount(task: Task) {
    console.log("次数加一", task.emp_id);
    try {
      //这里增加每个员工每日的任务数量限制
      const redisKey =
        `huozi-ai-material-creator:task:count:limit:` + task.emp_id;
      const count = await this.cacheService.incr(redisKey);
      const dayTaskCountLimit = 30;
      if (count > dayTaskCountLimit) {
        throw new QuantityExceededException(dayTaskCountLimit);
      }
    } catch (err) {
      console.log("err: ", err);
      return Promise.reject(err);
    }
  }

  /** 给当天累计生成次数减1 */
  private async taskCountDecr(task: Task) {
    this.logger.log("生成失败，次数减一", task.emp_id);
    try {
      // 获取当前key
      const redisKey =
        `huozi-ai-material-creator:task:count:limit:` + task.emp_id;
      await this.cacheService.decr(redisKey);
    } catch (err) {
      this.logger.log("decr err: ", err);
      return Promise.reject(err);
    }
  }

  async getTaskById(taskId: number): Promise<Task> {
    //通过id查询task并返回
    const FindOptionsWhere = { id: taskId };
    return await this.taskRepository.findOneBy(FindOptionsWhere);
  }

  async getTaskByPrompt(prompt: string): Promise<Task> {
    //通过id查询task并返回
    const FindOptionsWhere = { prompt: prompt, response_state: 1 };
    const promise = await this.taskRepository.find({
      where: FindOptionsWhere,
      order: { id: "DESC" },
    });
    if (promise.length > 0) {
      return promise[0];
    } else {
      return null;
    }
  }

  /**
   * 分页查询task
   * @param page,pageSize,empId
   */
  async getTasks(
    page: number = 1,
    pageSize: number = 10,
    empId = 0
  ): Promise<(Task[] | number)[]> {
    const skip = (page - 1) * pageSize;

    if (empId == 0) {
      const [tasks, total] = await this.taskRepository.findAndCount({
        take: pageSize,
        skip,
        order: { id: "DESC" },
      });
      return [tasks, total];
    } else {
      const [tasks, total] = await this.taskRepository.findAndCount({
        where: { emp_id: empId },
        take: pageSize,
        skip,
        order: { id: "DESC" },
      });
      return [tasks, total];
    }
  }

  async updateTask(task: Task) {
    //通过id更新task并返回
    const FindOptionsWhere = { id: task.id };
    const updateTask = await this.taskRepository.update(FindOptionsWhere, task);
  }

  async sendImageTask(task: Task) {
    const updateTask = new Task();
    updateTask.id = task.id;
    try {
      const result = await Promise.resolve({
        uri: "http://example.com/1.png",
        id: "123456",
      });
      this.logger.log("imagine result", JSON.stringify(result));
      updateTask.response = JSON.stringify(result);
      updateTask.response_state = 1;
      updateTask.response_time = new Date();
      updateTask.response_url = result.uri;
      updateTask.discord_session = result.id;
      updateTask.modified_time = new Date();
      this.updateTask(updateTask);
    } catch (err) {
      console.log("err: ", err);
      updateTask.response = JSON.stringify(err);
      updateTask.response_state = 2;
      updateTask.response_time = new Date();
      updateTask.response_url = "";
      updateTask.discord_session = "";
      updateTask.modified_time = new Date();
      this.updateTask(updateTask);
      // 任务生成失败，将次数返还
      this.taskCountDecr(task);
    }
  }

  async updateTaskProgress(task: Task, progress: string) {
    const updateTask = new Task();
    updateTask.id = task.id;
    updateTask.progress = progress;
    this.updateTask(updateTask);
  }

  async getCanUseCount(empId: number) {
    //这里增加每个员工每日的任务数量限制
    const redisKey = `huozi-ai-material-creator:task:count:limit:` + empId;
    const count = await this.cacheService.get(redisKey);
    const dayTaskCountLimit = 30;
    if (count == null) {
      return dayTaskCountLimit;
    }
    const countNumber = parseInt(count, 10);
    return dayTaskCountLimit - countNumber;
  }

  async resetUseCount(empId: number) {
    //这里增加每个员工每日的任务数量限制
    const redisKey = `huozi-ai-material-creator:task:count:limit:` + empId;
    await this.cacheService.del(redisKey);
  }
}
